From 0f26d15c7bab72a0ec3fbb01863f160b488dad42 Mon Sep 17 00:00:00 2001 From: Keir Fraser Date: Thu, 1 May 2008 09:50:16 +0100 Subject: [PATCH] Add SSL/TLS support to relocation * SSL/TLS support is disabled by default, as other server did. * If "xend-relocation-server-ssl-key-file" and "xend-relocation-server-ssl-cert-file" exist, SSL/TLS is enabled automatically. * "xend-relocation-tls" is used by relocation client only. Signed-off-by: Zhigang Wang --- tools/examples/xend-config.sxp | 9 ++++++ tools/python/xen/web/tcp.py | 41 ++++++++++++++++++++++++ tools/python/xen/xend/XendDomain.py | 10 +++++- tools/python/xen/xend/XendOptions.py | 11 +++++++ tools/python/xen/xend/server/relocate.py | 13 ++++++-- 5 files changed, 81 insertions(+), 3 deletions(-) diff --git a/tools/examples/xend-config.sxp b/tools/examples/xend-config.sxp index f3ee4f3a15..dc8a209922 100644 --- a/tools/examples/xend-config.sxp +++ b/tools/examples/xend-config.sxp @@ -82,6 +82,15 @@ # is set. #(xend-relocation-port 8002) +# Whether to use tls when relocating. +#(xend-relocation-tls no) + +# SSL key and certificate to use for the relocation interface. +# Setting these will mean that this port serves only SSL connections as +# opposed to plaintext ones. +#(xend-relocation-server-ssl-key-file /etc/xen/xmlrpc.key) +#(xend-relocation-server-ssl-cert-file /etc/xen/xmlrpc.crt) + # Address xend should listen on for HTTP connections, if xend-http-server is # set. # Specifying 'localhost' prevents remote connections. diff --git a/tools/python/xen/web/tcp.py b/tools/python/xen/web/tcp.py index 5ef94db619..f444c208d3 100644 --- a/tools/python/xen/web/tcp.py +++ b/tools/python/xen/web/tcp.py @@ -22,6 +22,8 @@ import re import socket import time +from OpenSSL import SSL + import connection from xen.xend.XendLogging import log @@ -64,3 +66,42 @@ class TCPListener(connection.SocketListener): sock.close() except: pass + +class SSLTCPListener(TCPListener): + + def __init__(self, protocol_class, port, interface, hosts_allow, + ssl_key_file = None, ssl_cert_file = None): + if not ssl_key_file or not ssl_cert_file: + raise ValueError("SSLXMLRPCServer requires ssl_key_file " + "and ssl_cert_file to be set.") + + self.ssl_key_file = ssl_key_file + self.ssl_cert_file = ssl_cert_file + + TCPListener.__init__(self, protocol_class, port, interface, hosts_allow) + + + def createSocket(self): + # make a SSL socket + ctx = SSL.Context(SSL.SSLv23_METHOD) + ctx.set_options(SSL.OP_NO_SSLv2) + ctx.use_privatekey_file (self.ssl_key_file) + ctx.use_certificate_file(self.ssl_cert_file) + sock = SSL.Connection(ctx, + socket.socket(socket.AF_INET, socket.SOCK_STREAM)) + sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) + + # SO_REUSEADDR does not always ensure that we do not get an address + # in use error when restarted quickly + # we implement a timeout to try and avoid failing unnecessarily + timeout = time.time() + 30 + while True: + try: + sock.bind((self.interface, self.port)) + return sock + except socket.error, (_errno, strerrno): + if _errno == errno.EADDRINUSE and time.time() < timeout: + time.sleep(0.5) + else: + raise + diff --git a/tools/python/xen/xend/XendDomain.py b/tools/python/xen/xend/XendDomain.py index 81dae6cd30..e821329400 100644 --- a/tools/python/xen/xend/XendDomain.py +++ b/tools/python/xen/xend/XendDomain.py @@ -1293,8 +1293,16 @@ class XendDomain: if port == 0: port = xoptions.get_xend_relocation_port() + try: - sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) + tls = xoptions.get_xend_relocation_tls() + if tls: + from OpenSSL import SSL + ctx = SSL.Context(SSL.SSLv23_METHOD) + sock = SSL.Connection(ctx, socket.socket(socket.AF_INET, socket.SOCK_STREAM)) + sock.set_connect_state() + else: + sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) sock.connect((dst, port)) except socket.error, err: raise XendError("can't connect: %s" % err[1]) diff --git a/tools/python/xen/xend/XendOptions.py b/tools/python/xen/xend/XendOptions.py index cae9a4d19a..35729af96d 100644 --- a/tools/python/xen/xend/XendOptions.py +++ b/tools/python/xen/xend/XendOptions.py @@ -192,6 +192,12 @@ class XendOptions: return self.get_config_bool("xend-relocation-server", self.xend_relocation_server_default) + def get_xend_relocation_server_ssl_key_file(self): + return self.get_config_string("xend-relocation-server-ssl-key-file") + + def get_xend_relocation_server_ssl_cert_file(self): + return self.get_config_string("xend-relocation-server-ssl-cert-file") + def get_xend_port(self): """Get the port xend listens at for its HTTP interface. """ @@ -203,6 +209,11 @@ class XendOptions: return self.get_config_int('xend-relocation-port', self.xend_relocation_port_default) + def get_xend_relocation_tls(self): + """Whether to use tls when relocating. + """ + return self.get_config_bool('xend-relocation-tls', 'no') + def get_xend_relocation_hosts_allow(self): return self.get_config_string("xend-relocation-hosts-allow", self.xend_relocation_hosts_allow_default) diff --git a/tools/python/xen/xend/server/relocate.py b/tools/python/xen/xend/server/relocate.py index 8f6a376bc4..e71820de20 100644 --- a/tools/python/xen/xend/server/relocate.py +++ b/tools/python/xen/xend/server/relocate.py @@ -132,5 +132,14 @@ def listenRelocation(): else: hosts_allow = map(re.compile, hosts_allow.split(" ")) - tcp.TCPListener(RelocationProtocol, port, interface = interface, - hosts_allow = hosts_allow) + ssl_key_file = xoptions.get_xend_relocation_server_ssl_key_file() + ssl_cert_file = xoptions.get_xend_relocation_server_ssl_cert_file() + + if ssl_key_file and ssl_cert_file: + tcp.SSLTCPListener(RelocationProtocol, port, interface = interface, + hosts_allow = hosts_allow, + ssl_key_file = ssl_key_file, + ssl_cert_file = ssl_cert_file) + else: + tcp.TCPListener(RelocationProtocol, port, interface = interface, + hosts_allow = hosts_allow) -- 2.30.2